#include "SerializeHelper.h"

std::ofstream& operator<<(std::ofstream& ofs, const gp_XYZ& xyz)
{
	Standard_Real x = xyz.X();
	Standard_Real y = xyz.Y();
	Standard_Real z = xyz.Z();

	ofs.write(reinterpret_cast<const char*>(&x), sizeof(Standard_Real));
	ofs.write(reinterpret_cast<const char*>(&y), sizeof(Standard_Real));
	ofs.write(reinterpret_cast<const char*>(&z), sizeof(Standard_Real));
	return ofs;
}

std::ofstream& operator<<(std::ofstream& ofs, const gp_Trsf& trsf)
{
	// 创建 4x4 矩阵
	NCollection_Mat4<Standard_Real> fullMatrix;
	trsf.GetMat4(fullMatrix); // 使用 GetMat4 填充矩阵

	// 序列化 4x4 矩阵
	for (int i = 0; i < 4; ++i)
	{
		for (int j = 0; j < 4; ++j)
		{
			double val = fullMatrix(i, j);
			ofs.write(reinterpret_cast<const char*>(&val), sizeof(double));
		}
	}

	return ofs;
}

std::ofstream& operator<<(std::ofstream& ofs, const gp_Mat& mat)
{
	for (int i = 1; i <= 3; ++i)
	{
		for (int j = 1; j <= 3; ++j)
		{
			Standard_Real val = mat(i, j);
			ofs.write(reinterpret_cast<const char*>(&val), sizeof(Standard_Real));
		}
	}
	return ofs;
}

std::ofstream& operator<<(std::ofstream& ofs, const gp_Ax2& ax2)
{
	ofs << ax2.Location() << ax2.Direction() << ax2.XDirection(); // 依次序列化原点和两个方向
	return ofs;
}

std::ofstream& operator<<(std::ofstream& ofs, const gp_Ax1& ax1)
{
	ofs << ax1.Location() << ax1.Direction(); // 依次序列化原点和方向
	return ofs;
}

std::ofstream& operator<<(std::ofstream& ofs, const gp_Dir& dir)
{
	ofs << dir.XYZ();
	return ofs;
}

std::ofstream& operator<<(std::ofstream& ofs, const gp_Pnt& pnt)
{
	ofs << pnt.XYZ();
	return ofs;
}

std::ofstream& operator<<(std::ofstream& ofs, const gp_Vec& vec)
{
	ofs << vec.XYZ();
	return ofs;
}

std::ifstream& operator>>(std::ifstream& ifs, gp_Trsf& trsf)
{
	// 创建 4x4 矩阵
	NCollection_Mat4<Standard_Real> fullMatrix;

	// 反序列化 4x4 矩阵
	for (int i = 0; i < 4; ++i)
	{
		for (int j = 0; j < 4; ++j)
		{
			double val;
			ifs.read(reinterpret_cast<char*>(&val), sizeof(double));
			fullMatrix(i, j) = val;
		}
	}

	// 从 NCollection_Mat4 转换为 gp_Trsf 需要手动提取值并使用 SetValues
	trsf.SetValues(fullMatrix(0, 0), fullMatrix(0, 1), fullMatrix(0, 2), fullMatrix(0, 3),
		fullMatrix(1, 0), fullMatrix(1, 1), fullMatrix(1, 2), fullMatrix(1, 3),
		fullMatrix(2, 0), fullMatrix(2, 1), fullMatrix(2, 2), fullMatrix(2, 3));

	return ifs;
}

std::ifstream& operator>>(std::ifstream& ifs, gp_Mat& mat)
{
	for (int i = 1; i <= 3; ++i)
	{
		for (int j = 1; j <= 3; ++j)
		{
			Standard_Real val;
			ifs.read(reinterpret_cast<char*>(&val), sizeof(Standard_Real));
			if (ifs.fail())
			{
				ifs.setstate(std::ios::failbit);
				return ifs;
			}
			mat(i, j) = val;
		}
	}
	return ifs;
}

std::ifstream& operator>>(std::ifstream& ifs, gp_Ax2& ax2)
{
	gp_Pnt location;
	gp_Dir direction;
	gp_Dir xDirection;

	ifs >> location >> direction >> xDirection;

	if (ifs.good())
	{
		ax2 = gp_Ax2(location, direction, xDirection);
	}
	else
	{
		ifs.setstate(std::ios::failbit);
	}
	return ifs;
}

std::ifstream& operator>>(std::ifstream& ifs, gp_Ax1& ax1)
{
	gp_Pnt location;
	gp_Dir direction;

	ifs >> location >> direction; // 依次反序列化原点和方向

	if (ifs.good())
	{
		ax1 = gp_Ax1(location, direction); // 设置 gp_Ax1 的值
	}
	else
	{
		ifs.setstate(std::ios::failbit); // 设置流状态为 failbit
	}
	return ifs;
}

std::ifstream& operator>>(std::ifstream& ifs, gp_Dir& dir)
{
	gp_XYZ xyz;
	ifs >> xyz;
	dir.SetXYZ(xyz);
	return ifs;
}

std::ifstream& operator>>(std::ifstream& ifs, gp_Pnt& pnt)
{
	gp_XYZ xyz;
	ifs >> xyz;
	pnt.SetXYZ(xyz);
	return ifs;
}

std::ifstream& operator>>(std::ifstream& ifs, gp_Vec& vec)
{
	gp_XYZ xyz;
	ifs >> xyz;
	vec.SetXYZ(xyz);
	return ifs;
}

std::ifstream& operator>>(std::ifstream& ifs, gp_XYZ& xyz)
{
	Standard_Real x, y, z;
	ifs.read(reinterpret_cast<char*>(&x), sizeof(Standard_Real));
	ifs.read(reinterpret_cast<char*>(&y), sizeof(Standard_Real));
	ifs.read(reinterpret_cast<char*>(&z), sizeof(Standard_Real));

	if (ifs.good())
	{
		xyz.SetCoord(x, y, z);
	}
	else
	{
		ifs.setstate(std::ios::failbit); // 设置流状态为 failbit，表示读取失败
	}
	return ifs;
}
